package lol.clann.bukkit.pluginboot.newcommand;

import lol.clann.bukkit.pluginboot.util.ServerUtils;
import lol.clann.bukkit.pluginboot.util.WorldUtils;
import lol.clann.clannboot.command.exception.CommandParamParseFailException;
import lol.clann.clannboot.command.parser.CommandParamParsers;
import lol.clann.clannboot.context.BeanContext;
import lol.clann.clannboot.util.clazz.ClassUtils;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.entity.Player;

import java.lang.reflect.Type;
import java.util.function.Predicate;

/**
 * 注册bukkit相关的参数
 *
 * @author pyz
 * @date 2018/11/30 9:20 PM
 */
public class CommandParserRegister {
    private static ServerUtils serverUtils;
    private static WorldUtils worldUtils;

    static {
        CommandParamParsers.registerCommandParser(new Predicate[]{type -> ClassUtils.isAssignableFrom(Player.class, (Type) type)}, type -> {
            return (sender, paramType, content) -> {
                Player p = getServerUtils().getPlayer(content);
                if (p == null) {
                    throw new CommandParamParseFailException("该玩家不存在或者不在线:" + content);
                } else {
                    return p;
                }
            };
        });

        CommandParamParsers.registerCommandParser(new Predicate[]{type -> type == OfflinePlayer.class}, type -> {
            return (sender, paramType, content) -> {
                OfflinePlayer p = getServerUtils().getOfflinePlayer(content);
                if (p == null) {
                    throw new CommandParamParseFailException("该玩家不存在:" + content);
                } else {
                    return p;
                }
            };
        });

        CommandParamParsers.registerCommandParser(new Predicate[]{type -> type == Material.class}, type -> {
            return (sender, paramType, content) -> {
                Material material;
                try {
                    Integer id = Integer.valueOf(content);
                    material = Material.getMaterial(id);
                } catch (NumberFormatException e) {
                    material = Material.getMaterial(content);
                }
                if (material == null) {
                    throw new CommandParamParseFailException("该物品不存在,id=" + content);
                } else {
                    return material;
                }
            };
        });

        CommandParamParsers.registerCommandParser(new Predicate[]{type -> type == World.class}, type -> {
            return (sender, paramType, content) -> {
                World w = getWorldUtils().getWorld(content);
                if (w == null) {
                    throw new CommandParamParseFailException("无效的世界名:worldName=" + content);
                }
                return w;
            };
        });
    }


    private static ServerUtils getServerUtils() {
        if (serverUtils == null) {
            serverUtils = BeanContext.getBean(ServerUtils.class);
        }
        return serverUtils;
    }

    public static WorldUtils getWorldUtils() {
        if (worldUtils == null) {
            worldUtils = BeanContext.getBean(WorldUtils.class);
        }
        return worldUtils;
    }
}
